package com.iwhalecloud.citybrain.flow.platform.manager.application.service;

import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.CandidateRelationShipEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowParticipantInfoVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.User;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.userentity.*;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowParticipantRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowUserRelationShipRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowUserTaskCustomExpressionRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.UserRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author: liyang
 * @date: 2021/11/5 16:30
 */
@Service
public class ResolveCandidateService {



    @Autowired
    private UserOrgService userOrgService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserGroupService userGroupService;

    @Autowired
    private UserPositionService userPositionService;

    @Autowired
    private UserRelationShipService userRelationShipService;

    @Autowired
    private FlowUserTaskCustomExpressionRepository flowUserTaskCustomExpressionRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private FlowParticipantRepository flowParticipantRepository;

    @Autowired
    private FlowUserRelationShipRepository flowUserRelationShipRepository;

    public List<UserInfo> getUserInfoByCode(String type, String code, String applyUser){
        if (Objects.equals("ORG",type)){
            return userOrgService.getUserListByOrgId(code);
        }else if (Objects.equals("ROL",type)){
            return userRoleService.getUserListByRoleId(code);
        }else if (Objects.equals("GROUP",type)){
            //TODO 接口未提供
            return userGroupService.getUserListByGroupId(code, null);
        }else if (Objects.equals("POSITION",type)){
            return userPositionService.getUserListByPositionId(code);
        }else if (Objects.equals("RELATIONSHIP",type)){
            // 拟稿人类型
            if(Objects.equals(CandidateRelationShipEnum.NGR.getCode(),type) &&
                    StringUtils.isNotBlank(applyUser)) {
                return this.convertApplyUserToUserInfo(applyUser);
            } else if(Objects.equals(CandidateRelationShipEnum.NGRBM.getCode(),type) ||
                    Objects.equals(CandidateRelationShipEnum.DQRBM.getCode(),type)) { // 拟稿人部门类型
                return this.convertOrgInfosToUserInfo(applyUser);
            }
        }
        return Collections.emptyList();
    }

    public CandidateEntity getCandidateEntity(String type,String code){
        FlowParticipantInfoVo flowParticipantInfoVo = flowParticipantRepository.findByIdAndType(code,type);
        if (Objects.nonNull(flowParticipantInfoVo) && StringUtils.isNotBlank(flowParticipantInfoVo.getParticipantName())){
            CandidateEntity candidateEntity = new CandidateEntity();
            candidateEntity.setCode(code);
            candidateEntity.setName(flowParticipantInfoVo.getParticipantName());
            candidateEntity.setType(type);
            return candidateEntity;
        }

        if (Objects.equals("STA",type) || Objects.equals("assignee",type)){
            User user = userRepository.getUserWithOrgByCodeFromUserCenter(code);
            if (Objects.nonNull(user)){
                CandidateEntity candidateEntity = convertObjectToCandidate(user, type);
                return candidateEntity;
            }
        }else if (Objects.equals("ORG",type)){
            OrgInfo orgInfo = userOrgService.getOrgByCode(code);
            if (Objects.nonNull(orgInfo)){
                CandidateEntity candidateEntity = convertObjectToCandidate(orgInfo, type);
                return candidateEntity;
            }

        }else if (Objects.equals("ROL",type)){
            RoleInfo roleInfo = userRoleService.getRoleInfoByCode(code);
            if (Objects.nonNull(roleInfo)){
                CandidateEntity candidateEntity = convertObjectToCandidate(roleInfo, type);
                return candidateEntity;
            }
        }else if (Objects.equals("GROUP",type)){
            GroupInfo groupInfo = userGroupService.getGroupDetail(Long.parseLong(code));
            if (Objects.nonNull(groupInfo)){
                CandidateEntity candidateEntity = convertObjectToCandidate(groupInfo, type);
                return candidateEntity;
            }
            return null;
        }else if (Objects.equals("POSITION",type)){
            PositionInfo positionInfo = userPositionService.getPositionDetail(Long.parseLong(code));
            if (Objects.nonNull(positionInfo)){
                CandidateEntity candidateEntity = convertObjectToCandidate(positionInfo, type);
                return candidateEntity;
            }
            return null;
        }else if (Objects.equals("RELATIONSHIP",type)){
            UserRelationShip userRelationShipInfo = flowUserRelationShipRepository.getUserRelationShipByShipType(code);
            if (Objects.nonNull(userRelationShipInfo)){
                CandidateEntity candidateEntity = convertObjectToCandidate(userRelationShipInfo, type);
                return candidateEntity;
            }
        }else{
            return null;
        }
        return null;
    }

    /**
     * 根据不同的数据类型和数据对象组装不同的数据
     * @param dataObj
     * @param dataType
     * @return
     */
    private CandidateEntity convertObjectToCandidate(Object dataObj, String dataType) {
        CandidateEntity candidateEntity = new CandidateEntity();
        switch (dataType) {
            case "STA":
            case "assignee":
                if(dataObj instanceof User) {
                    User userInfo = (User)dataObj;
                    candidateEntity.setCode(userInfo.getUserCode());
                    candidateEntity.setName(userInfo.getUserName());
                    candidateEntity.setType("STA");
                    break;
                }
            case "ROL":
                if(dataObj instanceof RoleInfo) {
                    RoleInfo roleInfo = (RoleInfo)dataObj;
                    candidateEntity.setCode(roleInfo.getRoleCode());
                    candidateEntity.setName(roleInfo.getRoleName());
                    candidateEntity.setType(dataType);
                    break;
                }
            case "ORG":
                if(dataObj instanceof OrgInfo) {
                    OrgInfo orgInfo = (OrgInfo)dataObj;
                    candidateEntity.setCode(orgInfo.getOrgCode());
                    candidateEntity.setName(orgInfo.getOrgName());
                    candidateEntity.setType(dataType);
                    break;
                }
            case "GROUP":
                if(dataObj instanceof GroupInfo) {
                    GroupInfo groupInfo = (GroupInfo)dataObj;
                    candidateEntity.setCode(groupInfo.getGroupCode());
                    candidateEntity.setName(groupInfo.getGroupName());
                    candidateEntity.setType(dataType);
                    break;
                }
            case "POSITION":
                if(dataObj instanceof PositionInfo) {
                    PositionInfo positionInfo = (PositionInfo)dataObj;
                    candidateEntity.setCode(positionInfo.getPositionCode());
                    candidateEntity.setName(positionInfo.getPositionName());
                    candidateEntity.setType(dataType);
                    break;
                }
            case "RELATIONSHIP":
                if(dataObj instanceof UserRelationShip) {
                    UserRelationShip userRelationShip = (UserRelationShip)dataObj;
                    candidateEntity.setCode(userRelationShip.getShipType());
                    candidateEntity.setName(userRelationShip.getShipName());
                    candidateEntity.setType(dataType);
                    break;
                }
            default:
                break;
        }
        //保存解析后的数据，方便下次查询
        addCandidateToParticipantInfo(candidateEntity);
        return candidateEntity;
    }

    private void addCandidateToParticipantInfo(CandidateEntity candidateEntity) {
        if (Objects.nonNull(candidateEntity)){
            FlowParticipantInfoVo flowParticipantInfoVo = new FlowParticipantInfoVo();
            flowParticipantInfoVo.setParticipantId(candidateEntity.getCode());
            flowParticipantInfoVo.setParticipantType(candidateEntity.getType());
            flowParticipantInfoVo.setParticipantName(candidateEntity.getName());
            flowParticipantRepository.insertParticipant(flowParticipantInfoVo);
        }
    }

    private List<UserInfo> convertApplyUserToUserInfo(String applyUser) {
        List<UserInfo> userInfos = new ArrayList<>();
        UserInfo userInfo = new UserInfo();
        userInfo.setUserCode(applyUser);
        userInfos.add(userInfo);
        return userInfos;
    }

    /**
     * 根据拟稿人或当前人ID获取人员信息
     *
     * @param applyUser
     * @return
     */
    private List<UserInfo> convertOrgInfosToUserInfo(String applyUser) {
        List<UserInfo> userInfoList = new ArrayList<>();
        // 根据拟稿人获取拟稿人对应的组织信息
        User userInfo = userService.getFullUserInfo(applyUser);
        if (Objects.isNull(userInfo)){
            return userInfoList;
        }

        // 根据组织获取对应的用户信息列表
        List<OrgInfo> orgInfos = userInfo.getOrgInfos();
        if(CollectionUtils.isNotEmpty(orgInfos)) {
          for (OrgInfo orgInfo:orgInfos) {
              userInfoList.addAll(userOrgService.getUserListByOrgId(orgInfo.getOrgCode()));
          }
        }
        return userInfoList;
    }
}
